import flet as ft
from flet import FilePickerUploadFile


def main(page: ft.Page):
    page.title = "1.9 Выбор и загрузка файлов (продвинутый)"
    page.padding = 20
    page.scroll = ft.ScrollMode.AUTO

    # ---------- СЛОВАРЬ ПРОГРЕСС-БАРОВ ПО ИМЕНИ ФАЙЛА ----------
    progress_bars = {}  # { "filename": ProgressBar }

    # Колонка, где будем показывать строки "название + прогресс"
    files_column = ft.Column()

    # Текст вверху — что сейчас выбрано
    info_text = ft.Text("Файлы не выбраны.")

    # Кнопка "Загрузить" — изначально выключена
    upload_button = ft.ElevatedButton(
        "Загрузить",
        on_click=None,   # позже подставим функцию
        disabled=True,
    )

    # ---------- FilePicker и обработчики ----------

    # когда диалог выбора/сохранения/папки закрывается
    def on_dialog_result(e):
        nonlocal progress_bars

        files_column.controls.clear()
        progress_bars.clear()

        if e.files is None:
            info_text.value = "Выбор файлов отменён."
            upload_button.disabled = True
        else:
            # Есть выбранные файлы
            names = [f.name for f in e.files]
            info_text.value = "Выбрано файлов: " + ", ".join(names)

            for f in e.files:
                # для каждого файла создаём ProgressBar и строку с именем
                pb = ft.ProgressBar(width=200, value=0)
                progress_bars[f.name] = pb

                row = ft.Row(
                    controls=[
                        ft.Text(f.name, width=250, no_wrap=True),
                        pb,
                    ],
                    alignment=ft.MainAxisAlignment.START,
                )
                files_column.controls.append(row)

            upload_button.disabled = False

        page.update()

    # когда идёт загрузка — сюда прилетает прогресс по каждому файлу
    def on_upload(e):
        file_name = e.file_name
        pb = progress_bars.get(file_name)

        if pb is None:
            return  # вдруг чего-то не совпало по имени

        if e.error:
            # если ошибка — показываем в тексте и ставим "неопределённый" прогресс
            pb.value = None
            pb.tooltip = f"Ошибка: {e.error}"
        else:
            pb.value = e.progress
            if e.progress >= 1:
                pb.tooltip = "Готово"

        pb.update()

    file_picker = ft.FilePicker(
        on_result=on_dialog_result,
        on_upload=on_upload,
    )

    # кладём FilePicker в overlay, чтобы не портить верстку
    page.overlay.append(file_picker)

    # ---------- КНОПКИ ----------

    # открыть диалог выбора файлов
    def pick_files(e):
        file_picker.pick_files(
            allow_multiple=True,
            # можно включить фильтры, если надо:
            # allowed_extensions=["jpg", "png", "pdf"],
            # file_type=ft.FilePickerFileType.CUSTOM
        )

    pick_button = ft.ElevatedButton(
        "Выбрать файлы...",
        on_click=pick_files,
    )

    # запуск загрузки выбранных файлов
    def upload_files(e):
        # проверяем, что что-то вообще выбрано
        if file_picker.result is None or file_picker.result.files is None:
            info_text.value = "Сначала выберите файлы."
            upload_button.disabled = True
            page.update()
            return

        upload_list = []

        for f in file_picker.result.files:
            # создаём объект FilePickerUploadFile с presigned URL
            upload_list.append(
                FilePickerUploadFile(
                    f.name,
                    upload_url=page.get_upload_url(f.name, 600),
                )
            )

        # запускаем асинхронную загрузку файлов
        file_picker.upload(upload_list)

    upload_button.on_click = upload_files

    # ---------- РАЗМЕТКА СТРАНИЦЫ ----------

    page.add(
        ft.Text("1.9 Выбор и загрузка файлов (продвинутый пример)", size=22, weight="bold"),
        ft.Text(
            "1) Нажми «Выбрать файлы...»\n"
            "2) Затем «Загрузить» — внизу увидишь прогресс по каждому файлу.\n"
            "Файлы сохранятся в папку 'uploads' рядом со скриптом.",
        ),
        ft.Row([pick_button, upload_button], spacing=10),
        info_text,
        ft.Divider(),
        ft.Text("Файлы и прогресс загрузки:", weight="bold"),
        files_column,
    )


if __name__ == "__main__":
    # Важно: upload_dir указывает, куда Flet будет складывать загруженные файлы
    ft.app(target=main, upload_dir="uploads")
